/**
 * @brief 3.5.5 与旧代码的接口
 * 很多C++程序在标准库出现之前就已经写成了，它们肯定没用到string和vector类型。
 * 而且，有一些C++程序实际上是与C语言或其他语言的接口程序，当然也无法使用C++标准库。
 * 因此，现代的C++程序不得不与那些充满了数组和/或C风格字符串的代码衔接，为了使这一工作简单易行，C++专门提供了一组功能。
 */
#include <iostream>
#include <cstring> // 可用于操作C风格字符串的函数，它们定义在cstring头文件中
#include <vector>
#include <iterator>
using std::cin, std::cout, std::endl;
using std::string;
using std::vector;
using std::begin, std::end;

int main(int argc, char const *argv[])
{
    // 如果程序的某处需要一个C风格字符串，无法直接用string对象来代替它。
    // 例如，不能用string对象直接初始化指向字符的指针。为了完成该功能，string专门提供了一个名为c_str的成员函数
    string s = "a";
    //char *str = s; // 错误，不能用string对象初始化char*
    const char *str = s.c_str(); // 正确，c_str函数的返回值是一个C风格的字符串。也就是说，函数的返回结果是一个指针
    cout << *str << endl;

    // 允许使用以空字符结束的字符数组来初始化string对象或为string对象赋值。
    char ch1[] = {'C','+','+','\0'};
    string s1(ch1);
    cout << s1 << endl;

    // 在string对象的加法运算中允许使用以空字符结束的字符数组作为其中一个运算对象（不能两个运算对象都是）
    char ch2[] = {'6','6','6','\0'};
    string s2 = s1 + " " + ch2;
    cout << s2 << endl;

    // 在string对象的复合赋值运算中允许使用以空字符结束的字符数组作为右侧的运算对象
    string s3 = s2 += ch2;
    cout << s3 << endl;

    // 使用数组初始化vector对象
    // 3.5.1节（第102页）介绍过不允许使用一个数组为另一个内置类型的数组赋初值，也不允许使用vector对象初始化数组。
    // 相反的，允许使用数组来初始化vector对象。要实现这一目的，只需指明要拷贝区域的首元素地址和尾后地址就可以了
    int int_arr[] = {0,1,2,3,4,5};
    vector<int> ivec(begin(int_arr),end(int_arr));

    // 使用指针和数组很容易出错。一部分原因是概念上的问题：指针常用于底层操作，因此容易引发一些与烦琐细节有关的错误。
    // 其他问题则源于语法错误，特别是声明指针时的语法错误。
    // 现代的C++程序应当尽量使用vector和迭代器，避免使用内置数组和指针；应该尽量使用string，避免使用C风格的基于数组的字符串。

    return 0;
}
